#include "xLogOutput.h"
#include "xLogUtil.h"
#include <map>
#include <sys/stat.h>
#include <unistd.h>
namespace XLog
{
    XLogOutputFile::XLogOutputFile(const char* fileName) : \
    strFileName(fileName),\
    strLogDir("log/"),
    lastUpateLogFileTime(XLogUtil::GetCurTime()),
    filePtr(NULL),
    isInit(false)
    {
        this->init();
    }

    XLogOutputFile::~XLogOutputFile()
    {
        if(filePtr)
        {
            fflush(filePtr);
            fclose(filePtr);
        } 
    }

    void XLogOutputFile::out(const XLogEvent* event,XLogFormat* format)
    {
        if(!isInit) return ;
        this->checkUpateFile();
        std::string str = format->out(event);
        fprintf(filePtr, "%s",str.c_str());
        fprintf(filePtr, "\n" );
    }

    bool XLogOutputFile::init()
    {
        return isInit = this->open();
    }

    bool XLogOutputFile::open()
    {
        if ( -1 == access( strLogDir.c_str(), F_OK ) )
        {
            mkdir( strLogDir.c_str(), 0755 );
            chmod( strLogDir.c_str(), 0755 );
        }
        std::string fullPath = strLogDir + std::string(strFileName);
        filePtr = fopen(fullPath.c_str(), "a+" );
        return filePtr == NULL ? false : true;
    }
    void XLogOutputFile::checkUpateFile()
    {
        time_t cur_t = XLogUtil::GetCurTime();
        if ( !XLogUtil::IsSameDay( lastUpateLogFileTime, cur_t ) )
        {
            changeLogFile();
            lastUpateLogFileTime = cur_t;
        }
    }
    void XLogOutputFile::changeLogFile()
    {
        if ( filePtr )
        {
            fflush( filePtr );
            fclose( filePtr );
        }
        std::string logname = strLogDir + std::string(strFileName);
        struct stat file_stat;
        if ( stat( logname.c_str(), &file_stat ) == 0 )	
        {
            std::string storefile = strLogDir + std::string(strFileName) + "." +  XLogUtil::GetTimestampStr( lastUpateLogFileTime );
            //重命名文件
            rename( logname.c_str(), storefile.c_str() );
        }
        this->open();
    }

    void XLogOutputConsole::out(const XLogEvent* event,XLogFormat* format)
    {
        const std::string out = format->out(event);
        std::cout << out << std::endl;
    }
}